#!/usr/bin/perl
#
# Copyright 2002-2005 Marc Tremblay
#
# This file is part of ExpireMail.
#
# ExpireMail is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# ExpireMail is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ExpireMail; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# expirefolder FOLDER <DAYS | DATE>
#
# Deletes mail from FOLDER that is older than DAYS, or whose date is before
# DATE.  DATE can be in any format that Date::EzDate can parse as long as it
# contains at least one space.
#
# $Id$

use Date::EzDate;
use POSIX qw(:signal_h);

sub usage {
    my($progname) = $0;
    $progname =~ s/.*\///;
    die "usage: $progname <folder> <days | date>";
}

if (@ARGV != 2) {
    &usage;
}

my($folder, $cutoff) = @ARGV;
my($tmpdir)="/tmp/expiremail.$$";

print `lockfile "$folder.lock"`;

# read the owner, group and file permissions so we can restore them later
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
                      $atime,$mtime,$ctime,$blksize,$blocks)
                          = stat($folder);
                          
my($permissions) = sprintf("%04o", $mode & 07777);

print `rm -rf $tmpdir`;
print `mkdir $tmpdir`;

$mydir = `dirname $0`;
chomp($mydir);
$splitmail = join('/', $mydir, 'splitmail');
print `formail -s procmail -m $splitmail $tmpdir < "$folder"`;

my($cutoffdatetime);
if ($cutoff =~ /\s/) {
    $cutoffdatetime = Date::EzDate->new($cutoff);
}
else {
    $cutoffdatetime = Date::EzDate->new();
    $cutoffdatetime->{'epochday'} -= $days;
}
$Date::EzDate::overload = 'epochsec';

opendir(DIR, $tmpdir);
my(@messages) = readdir(DIR);
closedir(DIR);

$day = '(Mon|Tue|Wed|Thu|Fri|Sat|Sun)';
$month = '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)';

my($sigset) = POSIX::SigSet->new();
my($blockset) = POSIX::SigSet->new(SIGINT, SIGQUIT, SIGCHLD);
sigprocmask(SIG_BLOCK, $blockset, $sigset) or die "Could not block INT, QUIT, and CHLD signals: $!\n";

print `mv "$folder" "$folder.bak"`;
print `touch "$folder"`;
while (@messages) {
    my($message) = shift(@messages);
    
    if (($message eq '.') || ($message eq '..')) {
	next;
    }
    
    $message_file = "$tmpdir/$message";
    open(MSG, "$message_file") || die "Couldn't open $message_file";
    @data = <MSG>;
    close(MSG);
    
    my($msgdate);
    while (@data) {
	my($line) = shift(@data);
	
	if ($line =~ /^From \S+ +$day $month +([0-9]+) ([0-9:]+) ([0-9]+)/) {
	    $msgdate = "$4 $2 $3, $5";
            last;
	}
	elsif ($line =~ /^Date: ($day, )?([0-9]+) $month ([0-9]+) ([0-9:]+)/) {
	    $msgdate = "$6 $4 $3, $5";
	    last;
	}
    }
    
    $messagedatetime = Date::EzDate->new($msgdate);
    
    if ($messagedatetime > $cutoffdatetime) {
	print `cat $message_file >> "$folder"`;
    }
}
sigprocmask(SIG_SETMASK, $sigset) or die "Could not restore INT, QUIT, and CHLD signals: $!\n";

# restore owner, group, and permissions
chown($uid, $gid, $folder);
chmod(oct($permissions), $folder);

unlink "$folder.bak";
unlink "$folder.lock";
print `rm -rf $tmpdir`;
exit;
